home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / sig / sigStubs.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  13KB  |  492 lines

  1. /* 
  2.  * sigStubs.c --
  3.  *
  4.  *    Stubs for Unix compatible system calls.
  5.  *
  6.  * Copyright 1990 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/sig/sigStubs.c,v 1.8 92/05/10 14:17:08 shirriff Exp $";
  18. #endif /* not lint */
  19.  
  20. #define MACH_UNIX_COMPAT
  21.  
  22. #include <sprite.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <status.h>
  26. #include <errno.h>
  27. #include <user/sys/types.h>
  28. #include <user/sys/wait.h>
  29. #include <user/sys/time.h>
  30. #include <user/sys/resource.h>
  31. #include <user/sys/signal.h>
  32. #include <mach.h>
  33. #include <proc.h>
  34. #include <procUnixStubs.h>
  35. #include <vm.h>
  36. #include <fsutil.h>
  37. #include <assert.h>
  38. #include <sig.h>
  39. #include <sigInt.h>
  40. #include <compatInt.h>
  41.  
  42. extern unsigned int     sigBitMasks[SIG_NUM_SIGNALS];
  43. extern int        sigDefActions[SIG_NUM_SIGNALS];
  44. extern int        sigCanHoldMask;
  45.  
  46. int debugSigStubs;
  47.  
  48.  
  49. /*
  50.  *----------------------------------------------------------------------
  51.  *
  52.  * Sig_KillStub --
  53.  *
  54.  *    Procedure to map from Unix kill system call to Sprite.
  55.  *
  56.  * Results:
  57.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  58.  *
  59.  * Side effects:
  60.  *    Side effects associated with the system call.
  61.  *
  62.  *----------------------------------------------------------------------
  63.  */
  64. int
  65. Sig_KillStub(pid, sig)
  66.     int pid;
  67.     int sig;
  68. {
  69.     ReturnStatus status;
  70.     int         spriteSignal;
  71.  
  72.     if (debugSigStubs) {
  73.     printf("Sig_KillStub(0x%x, 0x%x)\n", pid, sig);
  74.     }
  75.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  76.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  77.     status = SYS_INVALID_ARG;
  78.     } else {
  79.     if (pid == 0) {
  80.         pid = PROC_MY_PID;
  81.     }
  82.     status = Sig_UserSend(spriteSignal, pid, FALSE);
  83.     }
  84.     if (status != SUCCESS) {
  85.     Mach_SetErrno(Compat_MapCode(status));
  86.     return -1;
  87.     }
  88.     return 0;
  89. }
  90.  
  91.  
  92.  
  93. /*
  94.  *----------------------------------------------------------------------
  95.  *
  96.  * Sig_KillpgStub --
  97.  *
  98.  *    Procedure to map from Unix killpg system call to Sprite.
  99.  *
  100.  * Results:
  101.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  102.  *
  103.  * Side effects:
  104.  *    Side effects associated with the system call.
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108. int
  109. Sig_KillpgStub(pgrp, sig)
  110.     int pgrp;
  111.     int sig;
  112. {
  113.     ReturnStatus status;
  114.     int         spriteSignal;
  115.  
  116.     if (debugSigStubs) {
  117.     printf("Sig_KillpgStub(0x%x, 0x%x)\n", pgrp, sig);
  118.     }
  119.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  120.     if (status == FAILURE || (spriteSignal == NULL && sig != 0)) {
  121.     Mach_SetErrno(EINVAL);
  122.     return -1;
  123.     }
  124.     status = Sig_UserSend(spriteSignal, pgrp, TRUE);
  125.     if (status != SUCCESS) {
  126.     Mach_SetErrno(Compat_MapCode(status));
  127.     return -1;
  128.     }
  129.     return 0;
  130. }
  131.  
  132.  
  133.  
  134. /*
  135.  *----------------------------------------------------------------------
  136.  *
  137.  * Sig_SigvecStub --
  138.  *
  139.  *    Procedure to map from Unix sigvec system call to Sprite Sig_SetAction.
  140.  *
  141.  * Results:
  142.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  143.  *
  144.  * Side effects:
  145.  *    The signal handler associated with the specified signal is modified.
  146.  *
  147.  *----------------------------------------------------------------------
  148.  */
  149. int
  150. Sig_SigvecStub(sig, newVectorPtr, oldVectorPtr)
  151.     int         sig;        /* Signal to set the vector for. */
  152.     struct sigvec    *newVectorPtr;    /* New vector. */
  153.     struct sigvec    *oldVectorPtr;    /* Old vector. */
  154. {
  155.     int         spriteSignal;    /* Equivalent signal for Sprite */
  156.     Sig_Action         newAction;    /* Action to take */
  157.     Sig_Action         oldAction;    /* Former action */
  158.     ReturnStatus     status;        /* Generic result code */
  159.     struct sigvec newVector;
  160.     struct sigvec oldVector;
  161.     Proc_ControlBlock    *procPtr = Proc_GetActualProc();
  162.     Address        dummy;
  163.  
  164.     if (debugSigStubs) {
  165.     printf("Sig_SigvecStub(%d, %x, %x)\n", sig, newVectorPtr,
  166.         oldVectorPtr);
  167.     }
  168.  
  169.     /*
  170.      * Set magic flag to indicate we're in Unix signal mode.
  171.      */
  172.     procPtr->unixProgress = PROC_PROGRESS_UNIX;
  173.  
  174.     status = Compat_UnixSignalToSprite(sig, &spriteSignal);
  175.     if (status == FAILURE || spriteSignal == NULL) {
  176.     Mach_SetErrno(EINVAL);
  177.     return -1;
  178.     }
  179.     if (newVectorPtr != (struct sigvec *)NULL) {
  180.     status = Vm_CopyIn(sizeof(struct sigvec), (Address)newVectorPtr,
  181.                (Address)&newVector);
  182.     if (status != SUCCESS) {
  183.         Mach_SetErrno(Compat_MapCode(status));
  184.         return -1;
  185.     }
  186.     switch ((int)newVector.sv_handler) {
  187.         case SIG_DFL:
  188.         newAction.action = SIG_DEFAULT_ACTION;
  189.         break;
  190.         case SIG_IGN:
  191.         newAction.action = SIG_IGNORE_ACTION;
  192.         break;
  193.         default:
  194.         newAction.action = SIG_HANDLE_ACTION;
  195.         newAction.handler = (int (*)())newVector.sv_handler;
  196.     }
  197.     status = Compat_UnixSigMaskToSprite(newVector.sv_mask,
  198.                         &newAction.sigHoldMask);
  199.     if (status == FAILURE) {
  200.         printf("Sig_SigvecStub: compat failure\n");
  201.         Mach_SetErrno(EINVAL);
  202.         return -1;
  203.     }
  204.     /*
  205.      * Make sure that the signal is in range.
  206.      */
  207.     if (spriteSignal < SIG_MIN_SIGNAL || spriteSignal >= SIG_NUM_SIGNALS || 
  208.     spriteSignal == SIG_KILL || spriteSignal == SIG_SUSPEND) {
  209.         /*
  210.         printf("Sig_SigvecStub: bad signal %d\n", spriteSignal);
  211.         */
  212.         Mach_SetErrno(EINVAL);
  213.         return -1;
  214.     }
  215.     /* 
  216.          * There are two cases:
  217.          *
  218.      *    1) The current action really contains a handler to call.  Thus
  219.      *    the current action is SIG_HANDLE_ACTION.
  220.      *    2) The current action is one of the other four actions.
  221.      */
  222.     if (procPtr->sigActions[spriteSignal] > SIG_NUM_ACTIONS) {
  223.         oldAction.action = SIG_HANDLE_ACTION;
  224.         oldAction.handler = (int (*)())procPtr->sigActions[spriteSignal];
  225.         oldAction.sigHoldMask = procPtr->sigMasks[spriteSignal];
  226.     } else {
  227.         if (procPtr->sigActions[spriteSignal]
  228.             == sigDefActions[spriteSignal]) {
  229.         oldAction.action = SIG_DEFAULT_ACTION;
  230.         } else {
  231.         oldAction.action = procPtr->sigActions[spriteSignal];
  232.         }
  233.     }
  234.  
  235.     /*
  236.      * Make sure that the action is valid.
  237.      */
  238.  
  239.     if (newAction.action < 0 || newAction.action > SIG_NUM_ACTIONS) {
  240.       printf("Sig_SigvecStub: invalid action %d\n", newAction.action);
  241.       Mach_SetErrno(EINVAL);
  242.       return -1;
  243.     }
  244.  
  245.     if (newAction.action == SIG_DEFAULT_ACTION) {
  246.         newAction.action = sigDefActions[spriteSignal];
  247.     }
  248.  
  249.       /*
  250.        * Store the action.  If it is SIG_HANDLE_ACTION then the handler
  251.        * is stored in place of the action.
  252.        */
  253.       if (newAction.action == SIG_HANDLE_ACTION) {
  254.       if (Vm_CopyIn(4, (Address) ((unsigned int) (newAction.handler)), 
  255.           (Address) &dummy) != SUCCESS) {
  256.           Mach_SetErrno(EFAULT);
  257.           return -1;
  258.       }
  259.       procPtr->sigMasks[spriteSignal] =  (sigBitMasks[spriteSignal]
  260.           | newAction.sigHoldMask) & sigCanHoldMask;
  261.       procPtr->sigActions[spriteSignal] = (unsigned int) newAction.handler;
  262.       } else if (newAction.action == SIG_IGNORE_ACTION) {
  263.  
  264.       /*
  265.        * Only actions that can be blocked can be ignored.  This prevents a
  266.        * user from ignoring a signal such as a bus error which would cause
  267.        * the process to take a bus error repeatedly.
  268.        */
  269.       if (sigBitMasks[spriteSignal] & sigCanHoldMask) {
  270.           procPtr->sigActions[spriteSignal] = SIG_IGNORE_ACTION;
  271.           Proc_Lock(procPtr);
  272.           SigClearPendingMask(procPtr, spriteSignal);
  273.           if (spriteSignal == SIG_SUSPEND) {
  274.           procPtr->genFlags &= ~(PROC_PENDING_SUSPEND |
  275.                      PROC_RESUME_PROCESS);
  276.           }
  277.           Proc_Unlock(procPtr);
  278.       } else {
  279.           Mach_SetErrno(EINVAL);
  280.           return -1;
  281.       }
  282.       procPtr->sigMasks[spriteSignal] = 0;
  283.       } else {
  284.       procPtr->sigActions[spriteSignal] = newAction.action;
  285.       procPtr->sigMasks[spriteSignal] = 0;
  286.       }
  287.     }
  288.     if (oldVectorPtr != NULL) {
  289.     switch (oldAction.action) {
  290.  
  291.       case SIG_DEFAULT_ACTION:
  292.           oldVector.sv_handler = SIG_DFL;
  293.           break;
  294.  
  295.       case SIG_IGNORE_ACTION:
  296.           oldVector.sv_handler = SIG_IGN;
  297.           break;
  298.  
  299.       default:
  300.           oldVector.sv_handler = (void (*)())oldAction.handler;
  301.           break;
  302.       }
  303.       (void) Compat_SpriteSigMaskToUnix(oldAction.sigHoldMask, 
  304.                                         &oldVector.sv_mask);
  305.           oldVector.sv_flags = 0;
  306.       status = Vm_CopyOut(sizeof(oldVector), (Address)&oldVector,
  307.                 (Address)oldVectorPtr);
  308.       if (status != SUCCESS) {
  309.           Mach_SetErrno(EFAULT);
  310.           return -1;
  311.       }
  312.       }
  313.       return 0;
  314. }
  315.  
  316.  
  317. /*
  318.  *----------------------------------------------------------------------
  319.  *
  320.  * Sig_SigblockStub --
  321.  *
  322.  *    Procedure to map from Unix sigblock system call to Sprite.
  323.  *
  324.  * Results:
  325.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  326.  *
  327.  * Side effects:
  328.  *    Side effects associated with the system call.
  329.  *
  330.  *----------------------------------------------------------------------
  331.  */
  332. int
  333. Sig_SigblockStub(mask)
  334.     int mask;            /* additional bits to mask */
  335. {
  336.     int spriteMask = 0;        /* equivalent mask for Sprite */
  337.     int oldSpriteMask;        /* old mask, in Sprite terms */
  338.     ReturnStatus status;    /* generic result code */
  339.     register    Proc_ControlBlock    *procPtr = Proc_GetActualProc();
  340.     int oldMask;
  341.  
  342.     if (debugSigStubs) {
  343.     printf("Sig_SigblockStub(%x)\n", mask);
  344.     }
  345.     status = Compat_UnixSigMaskToSprite(mask, &spriteMask);
  346.     if (status == FAILURE) {
  347.     Mach_SetErrno(EINVAL);
  348.     return -1;
  349.     }
  350.     oldSpriteMask = procPtr->sigHoldMask;
  351.     if (status == FAILURE) {
  352.     Mach_SetErrno(EINVAL);
  353.     return -1;
  354.     }
  355.  
  356.     procPtr->sigHoldMask = (spriteMask | oldSpriteMask) & sigCanHoldMask;
  357.     procPtr->specialHandling = 1;
  358.     status = Compat_SpriteSigMaskToUnix(oldSpriteMask, &oldMask);
  359.     if (status == FAILURE) {
  360.     Mach_SetErrno(EINVAL);
  361.     return -1;
  362.     }
  363.     return oldMask;
  364. }
  365.  
  366.  
  367. /*
  368.  *----------------------------------------------------------------------
  369.  *
  370.  * Sig_SigsetmaskStub --
  371.  *
  372.  *    Procedure to map from Unix sigsetmask system call to Sprite.
  373.  *
  374.  * Results:
  375.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  376.  *
  377.  * Side effects:
  378.  *    Side effects associated with the system call.
  379.  *
  380.  *----------------------------------------------------------------------
  381.  */
  382. int
  383. Sig_SigsetmaskStub(mask)
  384.     int mask;            /* new mask */
  385. {
  386.     int spriteMask = 0;        /* equivalent mask for Sprite */
  387.     int oldSpriteMask;        /* old mask, in Sprite terms */
  388.     ReturnStatus status;    /* generic result code */
  389.     int oldMask;
  390.     register    Proc_ControlBlock    *procPtr;
  391.  
  392.     if (debugSigStubs) {
  393.     printf("Sig_SigsetmaskStub(%x)\n");
  394.     }
  395.  
  396.     procPtr = Proc_GetActualProc();
  397.     status = Compat_UnixSigMaskToSprite(mask,&spriteMask);
  398.     if (status == FAILURE) {
  399.     Mach_SetErrno(EINVAL);
  400.     return -1;
  401.     }
  402.     procPtr->sigHoldMask = spriteMask & sigCanHoldMask;
  403.     oldSpriteMask = procPtr->sigHoldMask;
  404.     procPtr->sigHoldMask = spriteMask & sigCanHoldMask;
  405.     procPtr->specialHandling = 1;
  406.     status = Compat_SpriteSigMaskToUnix(oldSpriteMask, &oldMask);
  407.     if (status == FAILURE) {
  408.     Mach_SetErrno(EINVAL);
  409.     return -1;
  410.     }
  411.     return oldMask;
  412. }
  413.  
  414.  
  415. /*
  416.  *----------------------------------------------------------------------
  417.  *
  418.  * Sig_SigpauseStub --
  419.  *
  420.  *    Procedure to map from Unix sigpause system call to Sprite.
  421.  *
  422.  * Results:
  423.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  424.  *
  425.  * Side effects:
  426.  *    Side effects associated with the system call.
  427.  *
  428.  *----------------------------------------------------------------------
  429.  */
  430. int
  431. Sig_SigpauseStub(mask)
  432.     int mask;            /* new mask */
  433. {
  434.     int spriteMask = 0;        /* equivalent mask for Sprite */
  435.     ReturnStatus status;    /* generic result code */
  436.  
  437.     if (debugSigStubs) {
  438.     printf("Sig_Sigpause\n");
  439.     }
  440.     status = Compat_UnixSigMaskToSprite(mask,&spriteMask);
  441.     if (status == FAILURE) {
  442.     Mach_SetErrno(EINVAL);
  443.     return -1;
  444.     }
  445.     status = Sig_Pause(spriteMask);
  446.     if (debugSigStubs) {
  447.     printf("Sig_Sigpause done\n");
  448.     }
  449.     Mach_SetErrno(EINTR);
  450.     if (status == GEN_ABORTED_BY_SIGNAL) {
  451.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_RESTART;
  452.     } else {
  453.     Proc_GetCurrentProc()->unixProgress = PROC_PROGRESS_MIG_RESTART;
  454.     }
  455.     return -1;
  456. }
  457.  
  458.  
  459. /*
  460.  *----------------------------------------------------------------------
  461.  *
  462.  * sigstack --
  463.  *
  464.  *    Procedure to fake the Unix sigstack system call.
  465.  *
  466.  * Results:
  467.  *    Error code is returned upon error.  Otherwise SUCCESS is returned.
  468.  *
  469.  * Side effects:
  470.  *    None.
  471.  *
  472.  *----------------------------------------------------------------------
  473.  */
  474. /*ARGSUSED*/
  475. int
  476. Sig_SigstackStub(ss, oss)
  477.     struct sigstack *ss, *oss;
  478. {
  479.     struct sigstack oldStack;
  480.  
  481.     if (debugSigStubs) {
  482.     printf("Sig_SigstackStub\n");
  483.     }
  484.     if (oss != NULL) {
  485.     oldStack.ss_sp = 0;
  486.     oldStack.ss_onstack = 0;
  487.     Vm_CopyOut(sizeof(struct sigstack), (Address)&oldStack,
  488.                       (Address)oss);
  489.     }
  490.     return 0;
  491. }
  492.